package com.xz.purchase.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xz.common.core.domain.entity.SysRole;
import com.xz.common.core.domain.model.LoginUser;
import com.xz.common.utils.StringUtils;
import com.xz.purchase.domain.*;
import com.xz.purchase.mapper.PurchaseProductMapper;
import com.xz.purchase.service.*;
import com.xz.purchase.vo.AllotInfoDataVo;
import com.xz.purchase.vo.AllotInfoVo;
import com.xz.purchase.vo.AllotProductVo;
import com.xz.audit.domain.ProcessInstance;
import com.xz.audit.dto.AuditDto;
import com.xz.audit.dto.AuditInfoDto;
import com.xz.audit.service.IAuditProcessService;
import com.xz.audit.service.IProcessInstanceService;
import com.xz.audit.service.impl.AuditInfoServiceImpl;
import com.xz.common.core.domain.AjaxResult;
import com.xz.common.exception.ServiceException;
import com.xz.common.utils.DateUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xz.common.utils.RedisCode;
import com.xz.common.utils.SecurityUtils;
import com.xz.repertory.service.IRepertoryFlowService;
import com.xz.warehouse.domain.Warehouse;
import com.xz.warehouse.service.IWarehouseService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;
import com.xz.purchase.mapper.AllotInfoMapper;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

/**
 * 库存调拨Service业务层处理
 *
 * @author xz
 * @date 2024-01-10
 */
@Service
public class AllotInfoServiceImpl extends ServiceImpl<AllotInfoMapper, AllotInfo> implements IAllotInfoService {
    @Autowired
    private AllotInfoMapper allotInfoMapper;
    @Autowired
    private IWarehouseService iWarehouseService;
    @Autowired
    private IRepertoryFlowService iRepertoryFlowService;
    @Autowired
    private IPurchaseProductService iPurchaseProductService;
    @Autowired
    private IPurchaseService iPurchaseService;
    @Autowired
    private IAllotProductService iAllotProductService;
    @Autowired
    private IAuditProcessService iAuditProcessService;
    @Autowired
    private IProcessInstanceService processInstanceService;
    @Autowired
    private PurchaseProductMapper purchaseProductMapper;
    @Autowired
    private IAllotPurchaseService iAllotPurchaseService;
    /**
     * 查询库存调拨
     *
     * @param id 库存调拨主键
     * @return 库存调拨
     */
    @Override
    public AllotProductVo selectAllotInfoById(Long id) {
        return allotInfoMapper.selectAllotInfoById(id);
    }

    /**
     * 查询库存调拨列表
     *
     * @param allotInfo 库存调拨
     * @return 库存调拨
     */
    @Override
    public List<AllotInfoVo> selectAllotInfoList(AllotInfo allotInfo) {
        allotInfo.setDeptId(SecurityUtils.getDeptId());
        //查询当前客户权限
        List<SysRole> roles = SecurityUtils.getLoginUser().getUser().getRoles();
        if(!CollectionUtils.isEmpty(roles)){
            String dataScope = roles.get(0).getDataScope();
            allotInfo.setDataScope(dataScope);
        }

        List<AllotInfoVo> allotInfoList = allotInfoMapper.selectAllotInfoList(allotInfo);
        //List<ProcessInstance> auditInfoList = processInstanceService.list(new QueryWrapper<ProcessInstance>().ne("audit_status", 2).eq("biz_type",1));
        allotInfoList.stream().forEach(item->{
            if(item.getStatus()==3) {
                if(item.getToDeptId()!=null&&item.getToDeptId().equals(SecurityUtils.getDeptId())){
                    item.setAuditName("待审核");
                    //流程状态（1.待审核 2.已完成 3.已驳回 4.重新发起）
                    item.setAuditType(1);
                    item.setAuditBut(1);
                }

               /* ProcessInstance auditInfo = processInstanceService.iAuditInfoService(item.getToDeptId(), item.getId(), SecurityUtils.getLoginUser().getUser(), auditInfoList);
                if (Objects.nonNull(auditInfo)) {
                    if (auditInfo.getAuditBut() != null) {
                        item.setAuditBut(auditInfo.getAuditBut());
                    }
                    item.setAuditName(auditInfo.getNodeName());
                    //流程状态（1.待审核 2.已完成 3.已驳回 4.重新发起）
                    item.setAuditType(auditInfo.getAuditStatus());
                }*/
            }
            if(item.getStatus()==4){
                if(SecurityUtils.getUsername().equals(item.getUserName())){
                    item.setAuditBut(3);
                    item.setAuditType(4);
                }
            }

        });
        return allotInfoList;
    }

    /**
     * 临时占用库存
     * @param allotProductList
     * @param allotInfo
     */
    public void temporaryOccupiedStock(List<AllotProduct> allotProductList,AllotInfo allotInfo){
        List<AllotPurchase> allotPurchaseList=new ArrayList<>();
        for(AllotProduct product:allotProductList){
            PurchaseProduct queryProductParam = new PurchaseProduct();
            BeanUtils.copyProperties(product,queryProductParam);
            queryProductParam.setDeptId(allotInfo.getDeptId());
            queryProductParam.setValidity(null);
            queryProductParam.setBatchDate(null);
            List<PurchaseProduct> purchaseProductList = purchaseProductMapper.getAllotListByParam(queryProductParam);
            if(!CollectionUtils.isEmpty(purchaseProductList)){
                Integer allotNum = product.getAllotNum();
                for(PurchaseProduct purchaseProduct:purchaseProductList){
                    AllotPurchase allotPurchase=new AllotPurchase();
                    if(allotNum>purchaseProduct.getAvailableStock()){
                        allotPurchase.setPurchaseProductNum(purchaseProduct.getAvailableStock());
                        allotNum=allotNum-purchaseProduct.getAvailableStock();
                        purchaseProduct.setAvailableStock(0);
                    }else{
                        purchaseProduct.setAvailableStock(purchaseProduct.getAvailableStock()-allotNum);
                        allotPurchase.setPurchaseProductNum(allotNum);
                        allotNum=0;
                    }
                    allotPurchase.setPurchaseProductId(purchaseProduct.getId());
                    allotPurchase.setAllotId(product.getAllotId());
                    allotPurchase.setDetailId(product.getId());
                    allotPurchaseList.add(allotPurchase);
                    purchaseProduct.setUpdateTime(new Date());
                    purchaseProductMapper.updatePurchaseProduct(purchaseProduct) ;

                    if(allotNum==0){
                        break;
                    }
                }
                if(allotNum>0){
                    throw new ServiceException("商品["+product.getProductName()+"]库存不足");
                }
            }
        }
        if(!CollectionUtils.isEmpty(allotPurchaseList)){
            iAllotPurchaseService.saveBatch(allotPurchaseList);
        }
   }

    /**
     * 新增库存调拨
     *
     * @param allotInfo 库存调拨
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult insertAllotInfo(AllotInfo allotInfo) {
        List<AllotProduct> allotProductList = allotInfo.getAllotProductList();
        if(CollectionUtils.isEmpty(allotProductList)){
            return AjaxResult.error("调拨商品不能为空");
        }
        //仓库所属部门
        Warehouse warehouse = iWarehouseService.getById(allotInfo.getOutWarehouseId());
        if(Objects.isNull(warehouse)){
            return AjaxResult.error("仓库不存在");
        }
        allotInfo.setDeptId(warehouse.getDeptId());
        allotInfo.setAllotNo(RedisCode.getCode("DB"));
        allotInfo.setCreateTime(DateUtils.getNowDate());
        allotInfo.setCreateBy(SecurityUtils.getUserId());
        allotInfo.setTenantId(SecurityUtils.getLoginUser().getTenantId());
        if(allotInfo.getStatus()==2&&iAuditProcessService.verifyProcess(1)){
            allotInfo.setStatus(3);
        }
        int insertAllotInfo = allotInfoMapper.insertAllotInfo(allotInfo);
        if(insertAllotInfo>0){
            allotProductList.stream().forEach(i-> {
                i.setAllotId(allotInfo.getId());
                i.setWarehouseId(allotInfo.getOutWarehouseId());
                i.setWarehouseName(allotInfo.getOutWarehouseName());
            });
            boolean saveAllotProduct = iAllotProductService.saveBatch(allotProductList);
            if(!saveAllotProduct){
                throw new ServiceException("新增调拨失败");
            }
            if(allotInfo.getStatus()==2){
                dataAllotProduct(allotProductList,allotInfo);
            }
            if(allotInfo.getStatus()==3){
                //发起审批
                AuditInfoDto auditInfoDto = new AuditInfoDto(1, allotInfo.getId().toString(),1);
                Boolean processInstance = processInstanceService.insertProcessInstance(auditInfoDto);
                if(!processInstance){
                    return AjaxResult.error("发起审批失败");
                }
                temporaryOccupiedStock(allotProductList,allotInfo);
            }
        }
        return insertAllotInfo>0? AjaxResult.success("新增成功"):AjaxResult.error("新增失败");
    }

    /**
     * 修改库存调拨
     *
     * @param allotInfo 库存调拨
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult updateAllotInfo(AllotInfo allotInfo) {
        List<AllotProduct> allotProductList = allotInfo.getAllotProductList();
        if(CollectionUtils.isEmpty(allotProductList)){
            return AjaxResult.error("调拨商品不能为空");
        }
        if(allotInfo.getId()==null){
            return AjaxResult.error("参数id不能为空");
        }
        AllotInfo byId = this.getById(allotInfo.getId());
        if(Objects.isNull(byId)){
            return AjaxResult.error("调拨信息不存在");
        }
        //调拨状态
        Integer status = byId.getStatus();
        allotInfo.setUpdateTime(DateUtils.getNowDate());
        //仓库所属部门
        Warehouse warehouse = iWarehouseService.getById(allotInfo.getOutWarehouseId());
        if(Objects.isNull(warehouse)){
            return AjaxResult.error("仓库不存在");
        }
        allotInfo.setUpdateTime(DateUtils.getNowDate());
        allotInfo.setUpdateBy(SecurityUtils.getUserId());
        if(allotInfo.getStatus()==2&&iAuditProcessService.verifyProcess(1)){
            allotInfo.setStatus(3);
        }
        int updateAllotInfo = allotInfoMapper.updateAllotInfo(allotInfo);
        if(updateAllotInfo>0){
            //删除调拨数据
            List<AllotPurchase> purchaseList = iAllotPurchaseService.list(new QueryWrapper<AllotPurchase>().eq("allot_id", allotInfo.getId()));
            if(!CollectionUtils.isEmpty(purchaseList)){
                for(AllotPurchase allotPurchase:purchaseList){
                    PurchaseProduct purchaseProduct = iPurchaseProductService.selectPurchaseProductById(allotPurchase.getPurchaseProductId());
                    if(Objects.nonNull(purchaseProduct)){
                        purchaseProduct.setAvailableStock(purchaseProduct.getAvailableStock()+allotPurchase.getPurchaseProductNum());
                        iPurchaseProductService.updatePurchaseProduct(purchaseProduct);
                    }
                    iAllotPurchaseService.deleteAllotPurchaseById(allotPurchase.getId());
                }
            }
            //删除更新前调拨数据
            iAllotProductService.deleteAllotProductById(allotInfo.getId());
            allotProductList.stream().forEach(i-> {
                i.setAllotId(allotInfo.getId());
                i.setWarehouseId(allotInfo.getOutWarehouseId());
                i.setWarehouseName(allotInfo.getOutWarehouseName());
            });
            boolean saveAllotProduct = iAllotProductService.saveBatch(allotProductList);
            if(!saveAllotProduct){
                throw new ServiceException("修改调拨失败");
            }
            if(allotInfo.getStatus()==2){
                allotInfo.setCreateBy(SecurityUtils.getUserId());
                allotInfo.setDeptId(warehouse.getDeptId());
                dataAllotProduct(allotProductList,allotInfo);
            }
            if(allotInfo.getStatus()==3 && status!=4) {//初始发起
                //发起审批
                AuditInfoDto auditInfoDto = new AuditInfoDto(1, allotInfo.getId().toString(),1);
                Boolean processInstance = processInstanceService.insertProcessInstance(auditInfoDto);
                if (!processInstance) {
                    return AjaxResult.error("发起审批失败");
                }
                temporaryOccupiedStock(allotProductList,byId);
            }
            if(status==4){//重新发起
                //发起审批
                temporaryOccupiedStock(allotProductList,byId);
                AuditInfoDto auditInfoDto = new AuditInfoDto(1, allotInfo.getId().toString(),2);
                Boolean processInstance = processInstanceService.insertProcessInstance(auditInfoDto);
                if (!processInstance) {
                    return AjaxResult.error("发起审批失败");
                }
            }
        }
        return updateAllotInfo>0? AjaxResult.success("修改成功"):AjaxResult.error("修改失败");
    }

    /**
     * 处理商品数据
     * @param allotProductList
     * @param allotInfo
     */
    public void dataAllotProduct(List<AllotProduct> allotProductList,AllotInfo allotInfo){
        //出库流水
        List<PurchaseProduct> outPurchaseProduct=new ArrayList<>();

        //入库流水
        List<PurchaseProduct> toPurchaseProduct=new ArrayList<>();
        List<PurchaseProduct> purchaseProductList = purchaseProductMapper.getAllotPurchaseProductMapper(allotInfo.getId());
        for (PurchaseProduct purchaseProduct:purchaseProductList){
            purchaseProduct.setRemark(purchaseProduct.getTaprRemark());
            purchaseProduct.setPurchaseNumber(allotInfo.getAllotNo());
            purchaseProduct.setBusinessId(purchaseProduct.getId());
        }
        outPurchaseProduct.addAll(purchaseProductList);
        if(CollectionUtils.isEmpty(outPurchaseProduct)) {
            throw new ServiceException("调拨失败");
        }
        for(PurchaseProduct purchaseProduct:outPurchaseProduct){
            purchaseProduct.setCreateTime(new Date());
            purchaseProduct.setCreateBy(allotInfo.getCreateBy());
            //库存没有对应商品，插入新数据
            Purchase purchase=new Purchase();
            purchase.setSupplierId(purchaseProduct.getSupplierId());
            purchase.setSupplierName(purchaseProduct.getSupplierName());
            purchase.setWarehouseId(allotInfo.getToWarehouseId());
            purchase.setWarehouseName(allotInfo.getToWarehouseName());
            purchase.setStatus(2);
            //仓库所属部门
            Warehouse warehouse = iWarehouseService.getById(allotInfo.getToWarehouseId());
            if(Objects.isNull(warehouse)){
                throw new ServiceException("调拨失败--仓库"+allotInfo.getToWarehouseName()+"不存在");
            }
            purchase.setDeptId(warehouse.getDeptId());
            purchase.setPurchaseNumber(RedisCode.getCode("RK"));
            purchase.setCreateTime(DateUtils.getNowDate());
            purchase.setCreateBy(SecurityUtils.getUserId());
            purchase.setTenantId(SecurityUtils.getLoginUser().getTenantId());
            iPurchaseService.save(purchase);
            PurchaseProduct product =new PurchaseProduct();
            BeanUtils.copyProperties(purchaseProduct,product);
            product.setId(null);
            product.setAvailableStock(purchaseProduct.getInventoryQuantity());
            product.setStorageNum(purchaseProduct.getInventoryQuantity());
            product.setWarehouseName(allotInfo.getToWarehouseName());
            product.setWarehouseId(allotInfo.getToWarehouseId());
            product.setPurchaseId(purchase.getId());
            product.setPurchaseNumber(allotInfo.getAllotNo());
            product.setDeptId(warehouse.getDeptId());
            product.setTenantId(allotInfo.getTenantId());
            product.setRelevancePurchaseId(purchaseProduct.getId());
            product.setCreateBy(allotInfo.getUpdateBy());
            product.setCreateTime(new Date());
            product.setRemark(purchaseProduct.getRemark());
            iPurchaseProductService.insertPurchaseProduct(product);
            //入库
            toPurchaseProduct.add(product);
        }
        boolean saveBatch = iRepertoryFlowService.saveRepertoryFlow(outPurchaseProduct, 2, 5);
        if (!saveBatch) {
            throw new ServiceException("调拨失败");
        }
        boolean repertoryFlow = iRepertoryFlowService.saveRepertoryFlow(toPurchaseProduct, 1, 6);
        if(!repertoryFlow){
            throw new ServiceException("调拨失败");
        }
    }
    /**
     * 批量删除库存调拨
     *
     * @param ids 需要删除的库存调拨主键
     * @return 结果
     */
    @Override
    public int deleteAllotInfoByIds(Long[] ids) {
        return allotInfoMapper.deleteAllotInfoByIds(ids);
    }

    /**
     * 删除库存调拨信息
     *
     * @param id 库存调拨主键
     * @return 结果
     */
    @Override
    public int deleteAllotInfoById(Long id) {
        int deleteAllotInfoById = allotInfoMapper.deleteAllotInfoById(id);
        if(deleteAllotInfoById>0){
            processInstanceService.updateProcessInstanceauditStatus(5,id.toString());
            //删除调拨数据
            List<AllotPurchase> purchaseList = iAllotPurchaseService.list(new QueryWrapper<AllotPurchase>().eq("allot_id", id));
            if(!CollectionUtils.isEmpty(purchaseList)){
                for(AllotPurchase allotPurchase:purchaseList){
                    PurchaseProduct purchaseProduct = iPurchaseProductService.selectPurchaseProductById(allotPurchase.getPurchaseProductId());
                    if(Objects.nonNull(purchaseProduct)){
                        purchaseProduct.setAvailableStock(purchaseProduct.getAvailableStock()+allotPurchase.getPurchaseProductNum());
                        iPurchaseProductService.updatePurchaseProduct(purchaseProduct);
                    }
                    iAllotPurchaseService.deleteAllotPurchaseById(allotPurchase.getId());
                }
            }
        }
        return deleteAllotInfoById;
    }

    /**
     * 审核
     * @param auditDto
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult allotInfoAudit(AuditDto auditDto) {
        AllotInfo allotInfo = allotInfoMapper.selectById(Long.parseLong(auditDto.getBizNo()));
        if(Objects.isNull(allotInfo)){
            return AjaxResult.error("审核失败");
        }
        auditDto.setBizType(1);
        int updateAuditInfo = processInstanceService.updateProcessInstance(auditDto);
        if(updateAuditInfo== AuditInfoServiceImpl.FINAL_NODE){//最后节点
            List<AllotProduct> productList = iAllotProductService.list(new QueryWrapper<AllotProduct>().eq("allot_id", allotInfo.getId()));
            allotInfo.setUpdateBy(SecurityUtils.getUserId());
            allotInfo.setUpdateTime(new Date());
            dataAllotProduct(productList,allotInfo);
            //完成调拨单
            allotInfo.setStatus(2);

            allotInfoMapper.updateAllotInfo(allotInfo);
        }
        if(updateAuditInfo== AuditInfoServiceImpl.FIRST_NODE){//重新发起
            //审核未通过
            allotInfo.setStatus(4);
            allotInfo.setUpdateBy(SecurityUtils.getUserId());
            allotInfo.setUpdateTime(new Date());
            allotInfoMapper.updateAllotInfo(allotInfo);
        }
        return AjaxResult.success("操作成功");
    }

    @Override
    public List<AllotInfoDataVo> getAllotInfoData() {
        return baseMapper.getAllotInfoData();
    }
}
